package com.xinan.ollama.milvus;

import com.google.common.collect.Lists;
import com.google.protobuf.ByteString;
import io.milvus.client.MilvusServiceClient;
import io.milvus.grpc.DataType;
import io.milvus.grpc.MutationResult;
import io.milvus.grpc.SearchResultData;
import io.milvus.grpc.SearchResults;
import io.milvus.param.ConnectParam;
import io.milvus.param.IndexType;
import io.milvus.param.MetricType;
import io.milvus.param.R;
import io.milvus.param.collection.*;
import io.milvus.param.dml.DeleteParam;
import io.milvus.param.dml.InsertParam;
import io.milvus.param.dml.SearchParam;
import io.milvus.param.index.CreateIndexParam;
import io.milvus.param.index.DropIndexParam;
import io.milvus.param.partition.*;
import io.milvus.response.SearchResultsWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Milvus工具类
 *
 * @author Administrator
 */
@Slf4j
@Component
public class MilvusUtil {

    private MilvusServiceClient milvusServiceClient;

    @Resource
    private MilvusConfiguration milvusConfiguration;

    private String collectionPrefix;
    private String highQualityGroupId = "";
    private List<String> collectionNameList = new ArrayList<>();
    private List<String> collectionLoadNameList = new ArrayList<>();
    private List<String> collectionAndPartitionNameList = new ArrayList<>();

    @PostConstruct
    private void connectToServer() {
        if (milvusConfiguration.milvusEnable) {
            collectionPrefix = milvusConfiguration.collectionPrefix;
            // 初始化向量库
            milvusServiceClient = new MilvusServiceClient(
                    ConnectParam.newBuilder()
                            .withHost(milvusConfiguration.host)
                            .withPort(milvusConfiguration.port)
                            .build());
            // 查询集合
            queryCollections();
        }
    }

    private void queryCollections() {
        collectionNameList = showCollectionsByParam();
        // 查询所有集合下的分区
        if (!CollectionUtils.isEmpty(collectionNameList)) {
            collectionAndPartitionNameList.clear();
            collectionNameList.forEach(collectionName -> {
                List<String> partitions = showPartitionsByParam(collectionName);
                if (!CollectionUtils.isEmpty(partitions)) {
                    partitions.forEach(partition -> {
                        collectionAndPartitionNameList.add(collectionName + "-" + partition);
                    });
                }
            });
        }
    }

    /**
     * 根据参数入库 Milvus
     *
     * @param collectionName 集合名称
     * @param partitionName  分区名称
     * @param content        内容
     * @param featureList    特征向量
     * @return 保存是否成功
     */
    public int insertEmbeddingToMilvus(String collectionName, String partitionName, String content, List<Float> featureList) {
        createCollectionByNames(collectionName, partitionName, milvusConfiguration.dimension);
        loadCollectionByAppId(collectionName);
        List<InsertParam.Field> fields = new ArrayList<>();
        fields.add(new InsertParam.Field("group_id", Collections.singletonList(partitionName)));
        fields.add(new InsertParam.Field("content", Collections.singletonList(content)));
        fields.add(new InsertParam.Field("content_feature", Collections.singletonList(featureList)));
        InsertParam insertParam = InsertParam.newBuilder()
                .withCollectionName(collectionPrefix + collectionName)
                .withPartitionName(partitionName)
                .withFields(fields)
                .build();
        R<MutationResult> insert = milvusServiceClient.insert(insertParam);
        return insert.getStatus();
    }


    /**
     * 根据参数创建集合
     *
     * @param collection_name 库ID
     * @param partition_name  分组ID
     * @param dimension       维度
     */
    private void createCollectionByNames(String collection_name, String partition_name, int dimension) {
        String collectionName = milvusConfiguration.collectionPrefix + collection_name;
        if (!collectionNameList.contains(collectionName)) {
            // 字段固定
            FieldType id = FieldType.newBuilder().withName("id")
                    .withDataType(DataType.Int64).withMaxLength(64).withPrimaryKey(true).withAutoID(true).build();
            FieldType groupId = FieldType.newBuilder().withName("group_id")
                    .withDataType(DataType.VarChar).withMaxLength(48).build();
            FieldType content = FieldType.newBuilder().withName("content")
                    .withDataType(DataType.VarChar).withMaxLength(1024).build();
            FieldType imageFeature = FieldType.newBuilder().withName("content_feature")
                    .withDataType(DataType.FloatVector).withDimension(dimension).build();
            List<FieldType> fieldTypes = Arrays.asList(id, groupId, content, imageFeature);
            createCollectionByParam(collectionName, fieldTypes, "contentAndFeature");
            createPartitionByParam(collectionName, partition_name);
            createIndexByParam(collectionName, "content_feature");
            // 刷新内存
            queryCollections();
        } else {
            String collectionAndPartitionName = collectionName + "_" + partition_name;
            if (!collectionAndPartitionNameList.contains(collectionAndPartitionName)) {
                createPartitionByParam(collectionName, partition_name);
            }
        }
    }

    /**
     * 根据参数创建集合
     *
     * @param collectionName 集合名称
     * @param fieldTypeList  字段列表
     * @param description    集合描述
     * @return 状态
     */
    public int createCollectionByParam(String collectionName, List<FieldType> fieldTypeList, String description) {
        Assert.notNull(collectionName, "collectionName  is null");
        boolean hasCollection = hasCollectionByParam(collectionName);
        int status = 1;
        if (!hasCollection) {
            // 创建参数
            CreateCollectionParam createCollectionParam = CreateCollectionParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withFieldTypes(fieldTypeList)
                    .withDescription(description)
                    .build();
            status = milvusServiceClient.createCollection(createCollectionParam).getStatus();
        }
        log.info("createCollectionByParam collectionName[{}] status[{}]", collectionName, status);
        return status;
    }


    /**
     * 根据参数搜索人脸
     *
     * @param collection_name 库ID
     * @param groupIdList     分组ID
     * @param feature         特征向量
     * @param topKey          获取几个搜索结果
     * @param matchThreshold  匹配率
     * @return 查询结果
     */
    public List<MilvusRes> searchContentByFeatureVector(String collection_name, List<String> groupIdList, List<Float> feature, int topKey, double matchThreshold) {
        String collectionName = collectionPrefix + collection_name;
        List<String> queryOutputFields = Arrays.asList("id", "content");
        SearchParam faceSearch;
        if (CollectionUtils.isEmpty(groupIdList)) {
            faceSearch = SearchParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withMetricType(MetricType.IP)
                    .withVectorFieldName("content_feature")
                    .withVectors(Collections.singletonList(feature))
                    .withOutFields(queryOutputFields)
                    .withRoundDecimal(3)
                    .withTopK(topKey).build();
        } else {
            faceSearch = SearchParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withPartitionNames(groupIdList)
                    .withMetricType(MetricType.IP)
                    .withVectorFieldName("content_feature")
                    .withVectors(Collections.singletonList(feature))
                    .withOutFields(queryOutputFields)
                    .withRoundDecimal(3)
                    .withTopK(topKey).build();
        }
        // 执行搜索
        long l = System.currentTimeMillis();
        R<SearchResults> respSearch = milvusServiceClient.search(faceSearch);
        log.info("MilvusServiceClient.search cost [{}]", System.currentTimeMillis() - l);
        // 解析结果数据
        Integer status = respSearch.getStatus();
        List<MilvusRes> milvusResList = new ArrayList<>();
        if (status == 0) {
            SearchResultData results = respSearch.getData().getResults();
            int scoresCount = results.getScoresCount();
            SearchResultsWrapper wrapperSearch = new SearchResultsWrapper(results);
            for (int i = 0; i < scoresCount; i++) {
                float score = wrapperSearch.getIDScore(0).get(i).getScore();
                if (score >= matchThreshold) {
                    Object idObj = wrapperSearch.getFieldData("id", 0).get(i);
                    Object contentObj = wrapperSearch.getFieldData("content", 0).get(i);
                    MilvusRes milvusRes = MilvusRes.builder()
                            .id(Long.parseLong(idObj.toString()))
                            .content(contentObj.toString())
                            .score(score * 100)
                            .build();
                    milvusResList.add(milvusRes);
                }
            }
        }
        return milvusResList;
    }


    /**
     * 用于动态处理高清库的分组ID
     */
    private void dealHighQualityGroupId() {
        String defaultPartitionName = "_default";
        String highQualityAppId = "";
        // 获取高清库的分区
        List<String> highQualityPartitionList = collectionAndPartitionNameList.stream()
                .filter(collectionAndPartitionName -> collectionAndPartitionName.contains(highQualityAppId))
                .collect(Collectors.toList());
        String partitionName = "";
        for (String highQualityPartition : highQualityPartitionList) {
            String[] names = highQualityPartition.split("-");
            String namePartition = names[1];
            String partitionStatistics = getPartitionStatisticsByParam(names[0], namePartition);
            if (StringUtils.isNotBlank(partitionStatistics)) {
                if (namePartition.equals(defaultPartitionName)) {
                    continue;
                }
                partitionName = namePartition;
                if (Integer.parseInt(partitionStatistics) < 666) {
                    highQualityGroupId = namePartition;
                    break;
                }
            }
        }
        // 创建
        if (StringUtils.isBlank(highQualityGroupId)) {
            if (StringUtils.isBlank(partitionName)) {
                createCollectionByAppId(highQualityAppId, "16160");
                loadCollectionByAppId(highQualityAppId);
            } else {
                int newGroupId = Integer.parseInt(partitionName) + 1;
                createCollectionByAppId(highQualityAppId, newGroupId + "");
            }

        }
    }

    /**
     * 根据参数入库Milvus
     *
     * @param collectionName 集合名称即：人脸库ID
     * @param partitionName  分区名称即：人脸库分组ID
     * @param id             数据ID
     * @param imagePath      图片路径
     * @param feature        图片特征向量
     * @return 保存是否成功
     */
    public int insertDataToMilvus(String collectionName, String partitionName, String id, String userId, String imagePath, float[] feature) {
        createCollectionByAppId(collectionName, partitionName);
        loadCollectionByAppId(collectionName);
        List<InsertParam.Field> fields = new ArrayList<>();
        List<Float> featureList = new ArrayList<>(feature.length);
        for (float v : feature) {
            featureList.add(v);
        }
        fields.add(new InsertParam.Field("id", Collections.singletonList(id)));
        fields.add(new InsertParam.Field("group_id", Collections.singletonList(partitionName)));
        fields.add(new InsertParam.Field("user_id", Collections.singletonList(userId)));
        fields.add(new InsertParam.Field("user_info", Collections.singletonList(imagePath)));
        fields.add(new InsertParam.Field("image_feature", Collections.singletonList(featureList)));
        InsertParam insertParam = InsertParam.newBuilder()
                .withCollectionName(collectionPrefix + collectionName)
                .withPartitionName(partitionName)
                .withFields(fields)
                .build();
        R<MutationResult> insert = milvusServiceClient.insert(insertParam);
        return insert.getStatus();
    }

    /**
     * 根据参数删除Milvus记录
     *
     * @param collectionName 集合名称即：人脸库ID
     * @param partitionName  分区名称即：人脸库分组ID
     * @param pkList         要删除的ID
     * @return 保存删除成功
     */
    public int deleteDataFromMilvus(String collectionName, String partitionName, List<String> pkList) {
        String pkInStr = pkList.stream().collect(Collectors.joining("\",\"", "\"", "\""));
        DeleteParam deleteParam;
        deleteParam = DeleteParam.newBuilder()
                .withCollectionName(collectionPrefix + collectionName)
                .withPartitionName(partitionName)
                .withExpr(String.format("id in [%s]", pkInStr))
                .build();
        R<MutationResult> delete = milvusServiceClient.delete(deleteParam);
        return delete.getStatus();
    }

    /**
     * 根据参数搜索人脸
     *
     * @param appid       人脸库ID
     * @param groupIdList 分组ID
     * @param feature     特征向量
     * @return 查询结果
     */
    public List<FaceIdentifyRes.UserInfo> searchImageByFeatureVector(String appid, List<String> groupIdList, float[] feature) {
        int topKey = 666;
        return searchImageByFeatureVector(appid, groupIdList, feature, topKey);
    }

    /**
     * 根据参数搜索人脸
     *
     * @param appid       人脸库ID
     * @param groupIdList 分组ID
     * @param feature     特征向量
     * @param topKey      获取几个搜索结果
     * @return 查询结果
     */
    public List<FaceIdentifyRes.UserInfo> searchImageByFeatureVector(String appid, List<String> groupIdList, float[] feature, int topKey) {
        double matchThreshold = 0.0;
        return searchImageByFeatureVector(appid, groupIdList, feature, topKey, matchThreshold);
    }


    /**
     * 根据参数搜索人脸
     *
     * @param appid          人脸库ID
     * @param groupIdList    分组ID
     * @param feature        特征向量
     * @param matchThreshold 匹配率
     * @return 查询结果
     */
    public List<FaceIdentifyRes.UserInfo> searchImageByFeatureVector(String appid, List<String> groupIdList, float[] feature, double matchThreshold) {
        int topKey = 666;
        return searchImageByFeatureVector(appid, groupIdList, feature, topKey, matchThreshold);
    }

    /**
     * 根据参数搜索人脸
     *
     * @param appid          人脸库ID
     * @param groupIdList    分组ID
     * @param feature        特征向量
     * @param topKey         获取几个搜索结果
     * @param matchThreshold 匹配率
     * @return 查询结果
     */
    public List<FaceIdentifyRes.UserInfo> searchImageByFeatureVector(String appid, List<String> groupIdList, float[] feature, int topKey, double matchThreshold) {
        String collectionName = collectionPrefix + appid;
        List<Float> featureList = new ArrayList<>(feature.length);
        for (float v : feature) {
            featureList.add(v);
        }
        List<String> queryOutputFields = Arrays.asList("group_id", "user_id", "user_info");
        SearchParam faceSearch;
        if (CollectionUtils.isEmpty(groupIdList)) {
            faceSearch = SearchParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withMetricType(MetricType.IP)
                    .withVectorFieldName("image_feature")
                    .withVectors(Collections.singletonList(featureList))
                    .withOutFields(queryOutputFields)
                    .withRoundDecimal(3)
                    .withTopK(topKey).build();
        } else {
            faceSearch = SearchParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withPartitionNames(groupIdList)
                    .withMetricType(MetricType.IP)
                    .withVectorFieldName("image_feature")
                    .withVectors(Collections.singletonList(featureList))
                    .withOutFields(queryOutputFields)
                    .withRoundDecimal(3)
                    .withTopK(topKey).build();
        }
        // 执行搜索
        long l = System.currentTimeMillis();
        R<SearchResults> respSearch = milvusServiceClient.search(faceSearch);
        log.info("MilvusServiceClient.search cost [{}]", System.currentTimeMillis() - l);
        // 解析结果数据
        Integer status = respSearch.getStatus();
        List<FaceIdentifyRes.UserInfo> milvusResList = new ArrayList<>();
        if (status == 0) {
            SearchResultData results = respSearch.getData().getResults();
            int scoresCount = results.getScoresCount();
            SearchResultsWrapper wrapperSearch = new SearchResultsWrapper(results);
            for (int i = 0; i < scoresCount; i++) {
                float score = wrapperSearch.getIDScore(0).get(i).getScore();
                if (score >= matchThreshold) {
                    Object groupId = wrapperSearch.getFieldData("group_id", 0).get(i);
                    Object userId = wrapperSearch.getFieldData("user_id", 0).get(i);
                    Object userInfo = wrapperSearch.getFieldData("user_info", 0).get(i);
                    FaceIdentifyRes.UserInfo milvusRes = FaceIdentifyRes.UserInfo.builder()
                            .group_id(groupId.toString())
                            .user_id(userId.toString())
                            .user_info(userInfo.toString())
                            .score(score * 100)
                            .build();
                    milvusResList.add(milvusRes);
                }
            }
        }
        return milvusResList;
    }

    /**
     * 根据参数查询所有集合
     *
     * @return 数据
     */
    public List<String> showCollectionsByParam() {
        ShowCollectionsParam showCollectionsParam = ShowCollectionsParam.newBuilder().build();
        List<ByteString> byteStrings = milvusServiceClient.showCollections(showCollectionsParam).getData().getCollectionNamesList().asByteStringList();
        List<String> collectionList = Lists.newLinkedList();
        byteStrings.forEach(s -> {
            collectionList.add(s.toStringUtf8());
        });
        return collectionList;
    }

    /**
     * 根据人脸库参数创建集合
     *
     * @param appid    人脸库ID
     * @param group_id 人脸库分组ID
     */
    private void createCollectionByAppId(String appid, String group_id) {
        String collectionName = milvusConfiguration.collectionPrefix + appid;
        if (!collectionNameList.contains(collectionName)) {
            // 字段固定
            FieldType id = FieldType.newBuilder().withName("id")
                    .withDataType(DataType.VarChar).withMaxLength(64).withPrimaryKey(true).withAutoID(false).build();
            FieldType groupId = FieldType.newBuilder().withName("group_id")
                    .withDataType(DataType.VarChar).withMaxLength(48).build();
            FieldType userId = FieldType.newBuilder().withName("user_id")
                    .withDataType(DataType.VarChar).withMaxLength(128).build();
            FieldType userInfo = FieldType.newBuilder().withName("user_info")
                    .withDataType(DataType.VarChar).withMaxLength(256).build();
            FieldType imageFeature = FieldType.newBuilder().withName("image_feature")
                    .withDataType(DataType.FloatVector).withDimension(1024).build();
            List<FieldType> fieldTypes = Arrays.asList(id, groupId, userId, userInfo, imageFeature);
            createCollectionByParam(collectionName, fieldTypes, "人脸搜索结合");
            createPartitionByParam(collectionName, group_id);
            createIndexByParam(collectionName, "image_feature");
            // 刷新内存
            queryCollections();
        } else {
            String collectionAndPartitionName = collectionName + "_" + group_id;
            if (!collectionAndPartitionNameList.contains(collectionAndPartitionName)) {
                createPartitionByParam(collectionName, group_id);
            }
        }
    }


    /**
     * 根据参数统计集合数据
     *
     * @param collectionName 集合名称
     * @return 数据
     */
    public String getCollectionStatisticsByParam(String collectionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        boolean hasPartition = hasCollectionByParam(collectionName);
        if (hasPartition) {
            // 创建参数
            GetCollectionStatisticsParam getCollectionStatisticsParam = GetCollectionStatisticsParam.newBuilder()
                    .withCollectionName(collectionName)
                    .build();
            String rowCount = milvusServiceClient.getCollectionStatistics(getCollectionStatisticsParam).getData().getStats(0).getValue();
            log.info("getCollectionStatisticsParam collectionName[{}] rowCount[{}]", collectionName, rowCount);
            return rowCount;
        } else {
            return null;
        }
    }

    /**
     * 根据参数判断集合是否存在
     *
     * @param collectionName 集合名称
     * @return 状态
     */
    public boolean hasCollectionByParam(String collectionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        // 创建参数
        HasCollectionParam hasCollectionParam = HasCollectionParam.newBuilder()
                .withCollectionName(collectionName)
                .build();
        boolean status = milvusServiceClient.hasCollection(hasCollectionParam).getData();
        log.info("hasCollectionByParam collectionName[{}] status[{}]", collectionName, status);
        return status;
    }

    /**
     * 根据参数载入集合
     *
     * @param collectionName 集合名称
     * @return 状态
     */
    public int loadCollectionByParam(String collectionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        // 创建参数
        LoadCollectionParam loadCollectionParam = LoadCollectionParam.newBuilder()
                .withCollectionName(collectionName)
                .build();
        int status = milvusServiceClient.loadCollection(loadCollectionParam).getStatus();
        log.info("loadCollectionByParam collectionName[{}] status[{}]", collectionName, status);
        return status;
    }

    /**
     * 根据参数载入集合
     *
     * @param appid 人脸库ID
     */
    private void loadCollectionByAppId(String appid) {
        String collectionName = milvusConfiguration.collectionPrefix + appid;
        if (!collectionLoadNameList.contains(collectionName)) {
            loadCollectionByParam(collectionName);
            collectionLoadNameList.add(collectionName);
        }
    }

    /**
     * 根据参数删除集合
     *
     * @param collectionName 集合名称
     * @return 状态
     */
    public int dropCollectionByParam(String collectionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        // 创建参数
        DropCollectionParam dropCollectionParam = DropCollectionParam.newBuilder()
                .withCollectionName(collectionName)
                .build();
        int status = milvusServiceClient.dropCollection(dropCollectionParam).getStatus();
        log.info("dropCollectionByParam collectionName[{}] status[{}]", collectionName, status);
        return status;
    }

    /**
     * 根据参数释放集合
     *
     * @param collectionName 集合名称
     * @return 状态
     */
    public int releaseCollectionByParam(String collectionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        // 创建参数
        ReleaseCollectionParam releaseCollectionParam = ReleaseCollectionParam.newBuilder()
                .withCollectionName(collectionName)
                .build();
        int status = milvusServiceClient.releaseCollection(releaseCollectionParam).getStatus();
        log.info("releaseCollectionByParam collectionName[{}] status[{}]", collectionName, status);
        return status;
    }

    /**
     * 根据参数查询所有分区
     *
     * @param collectionName 集合名称
     * @return 数据
     */
    public List<String> showPartitionsByParam(String collectionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        ShowPartitionsParam searchParam = ShowPartitionsParam.newBuilder().withCollectionName(collectionName).build();
        List<ByteString> byteStrings = milvusServiceClient.showPartitions(searchParam).getData().getPartitionNamesList().asByteStringList();
        List<String> partitionList = Lists.newLinkedList();
        byteStrings.forEach(s -> {
            partitionList.add(s.toStringUtf8());
        });
        return partitionList;
    }

    /**
     * 根据参数创建分区
     *
     * @param collectionName 集合名称
     * @param partitionName  分区名称
     * @return 状态
     */
    public int createPartitionByParam(String collectionName, String partitionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        Assert.notNull(partitionName, "partitionName  is null");
        // 创建参数
        boolean hasPartition = hasPartitionByParam(collectionName, partitionName);
        int status = 1;
        if (!hasPartition) {
            CreatePartitionParam createPartitionParam = CreatePartitionParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withPartitionName(partitionName)
                    .build();
            status = milvusServiceClient.createPartition(createPartitionParam).getStatus();
            log.info("addPartitionByName collectionName[{}] partitionName[{}] status[{}]", collectionName, partitionName, status);
        }
        return status;
    }

    /**
     * 根据参数统计分区数据
     *
     * @param collectionName 集合名称
     * @param partitionName  分区名称
     * @return 数据
     */
    public String getPartitionStatisticsByParam(String collectionName, String partitionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        Assert.notNull(partitionName, "partitionName  is null");
        boolean hasPartition = hasPartitionByParam(collectionName, partitionName);
        if (hasPartition) {
            // 创建参数
            GetPartitionStatisticsParam getPartitionStatisticsParam = GetPartitionStatisticsParam.newBuilder()
                    .withCollectionName(collectionName)
                    .withPartitionName(partitionName)
                    .build();
            String rowCount = milvusServiceClient.getPartitionStatistics(getPartitionStatisticsParam).getData().getStats(0).getValue();
            log.info("getPartitionStatisticsByParam collectionName[{}] partitionName[{}] rowCount[{}]", collectionName, partitionName, rowCount);
            return rowCount;
        } else {
            return null;
        }
    }

    /**
     * 根据参数判断分区是否存在
     *
     * @param collectionName 集合名称
     * @param partitionName  分区名称
     * @return 状态
     */
    public boolean hasPartitionByParam(String collectionName, String partitionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        Assert.notNull(partitionName, "partitionName  is null");
        // 创建参数
        HasPartitionParam hasPartitionParam = HasPartitionParam.newBuilder()
                .withCollectionName(collectionName)
                .withPartitionName(partitionName)
                .build();
        boolean status = milvusServiceClient.hasPartition(hasPartitionParam).getData();
        log.info("hasPartitionByName collectionName[{}] partitionName[{}] status[{}]", collectionName, partitionName, status);
        return status;
    }

    /**
     * 根据参数载入分区
     *
     * @param collectionName    集合名称
     * @param partitionNameList 分区名称列表
     * @return 状态
     */
    public int loadPartitionByParam(String collectionName, List<String> partitionNameList) {
        Assert.notNull(collectionName, "collectionName  is null");
        Assert.notNull(partitionNameList, "partitionName  is null");
        // 创建参数
        LoadPartitionsParam loadPartitionsParam = LoadPartitionsParam.newBuilder()
                .withCollectionName(collectionName)
                .withPartitionNames(partitionNameList)
                .build();
        int status = milvusServiceClient.loadPartitions(loadPartitionsParam).getStatus();
        log.info("loadPartitionByParam collectionName[{}] partitionNameList[{}] status[{}]", collectionName, partitionNameList, status);
        return status;
    }

    /**
     * 根据参数删除分区
     *
     * @param collectionName 集合名称
     * @param partitionName  分区名称
     * @return 状态
     */
    public int dropPartitionByParam(String collectionName, String partitionName) {
        Assert.notNull(collectionName, "collectionName  is null");
        Assert.notNull(partitionName, "partitionName  is null");
        // 创建参数
        DropPartitionParam dropPartitionParam = DropPartitionParam.newBuilder()
                .withCollectionName(collectionName)
                .withPartitionName(partitionName)
                .build();
        int status = milvusServiceClient.dropPartition(dropPartitionParam).getStatus();
        log.info("dropPartitionParam collectionName[{}] partitionName[{}] status[{}]", collectionName, partitionName, status);
        return status;
    }

    /**
     * 根据参数释放分区
     *
     * @param collectionName    集合名称
     * @param partitionNameList 分区名称列表
     * @return 状态
     */
    public int releasePartitionByParam(String collectionName, List<String> partitionNameList) {
        Assert.notNull(collectionName, "collectionName  is null");
        Assert.notNull(partitionNameList, "partitionName  is null");
        // 创建参数
        ReleasePartitionsParam releasePartitionsParam = ReleasePartitionsParam.newBuilder()
                .withCollectionName(collectionName)
                .withPartitionNames(partitionNameList)
                .build();
        int status = milvusServiceClient.releasePartitions(releasePartitionsParam).getStatus();
        log.info("releasePartitionsParam collectionName[{}] partitionName[{}] status[{}]", collectionName, partitionNameList, status);
        return status;
    }

    /**
     * 根据参数创建索引
     *
     * @param collectionName 集合名称
     * @param fieldName      字段名称
     * @return 状态
     */
    public int createIndexByParam(String collectionName, String fieldName) {
        Assert.notNull(collectionName, "collectionName  is null");
        Assert.notNull(fieldName, "fieldName  is null");
        // 创建参数
        final IndexType indexType = IndexType.IVF_FLAT;
        final String extraParam = "{\"nlist\":1024}";
        CreateIndexParam createIndexParam = CreateIndexParam.newBuilder()
                .withCollectionName(collectionName)
                .withFieldName(fieldName)
                .withIndexType(indexType)
                .withIndexName("idx_" + collectionName + "_" + fieldName)
                .withMetricType(MetricType.L2)
                .withExtraParam(extraParam)
                .withSyncMode(Boolean.FALSE)
                .build();
        int status = milvusServiceClient.createIndex(createIndexParam).getStatus();
        log.info("createIndexByParam collectionName[{}] fieldName[{}] status[{}]", collectionName, fieldName, status);
        return status;
    }

    /**
     * 根据参数删除索引
     *
     * @param collectionName 集合名称
     * @param fieldName      字段名称
     * @return 状态
     */
    public int dropIndexByParam(String collectionName, String fieldName) {
        Assert.notNull(collectionName, "collectionName  is null");
        Assert.notNull(fieldName, "fieldName  is null");
        // 创建参数
        DropIndexParam dropIndexParam = DropIndexParam.newBuilder()
                .withCollectionName(collectionName)
                .withIndexName("idx_" + collectionName + "_" + fieldName)
                .build();
        int status = milvusServiceClient.dropIndex(dropIndexParam).getStatus();
        log.info("dropIndexByParam collectionName[{}] fieldName[{}] status[{}]", collectionName, fieldName, status);
        return status;
    }

}
